using UnityEngine;
using System.Collections;

public class EnemyControl : CharacterControl<EnemyControl>
{
    #region Attributes

    /* Stats */
    public float checkSpeed = 4.0f;
    public float searchSpeed = 5.0f;

    /* Probabilities */
    public RandomRange probSearchFromNoise;
    public RandomRange probSearchFromAlert;
    [HideInInspector]
    public float probSearch;

    /* Ranges */
    public float viewRange = 21.0f;
    public float viewAngle = 60.0f;

    /* OffSets */
    public float waypointOffset = 1.0f;
    public float playerOffset = 1.5f;
    
    /* Waypoints */
    public bool roundTripWaypoints = true;
    public Transform[] waypoints;
    private int currentWaypoint = 0;
    private int waypointDirection = 1;
    private WaypointControl lastWaypointHit;

    /* Interest Points */
    [HideInInspector]
    public PlayerControl player;
    [HideInInspector]
    public Vector3 playerLastLocation;

    #endregion

    #region Props

    public Transform CurrentWaypoint
    {
        get 
        {
            return (this.currentWaypoint < this.waypoints.Length ?
                    this.waypoints[this.currentWaypoint] : null);
        }
    }

    public Vector3 PlayerDistance
    {
        get
        {
            return this.player.transform.position - this.transform.position;
        }
    }

    public Vector2 PlayerDistance2D
    {
        get
        {
            return this.ToVector2(this.player.transform.position) - this.Position2D;
        }
    }

    public WaypointControl LastWaypointHit
    {
        get { return this.lastWaypointHit; }
    }

    #endregion

    #region Methods

    public bool IsPlayerInViewRange()
    {
        bool result = false;
        Vector2 distance = this.PlayerDistance2D;
       
        /* IF in ViewRange and ViewAnge */
        if (distance.magnitude <= this.viewRange &&
            Vector2.Angle(this.Forward2D, distance) <= this.viewAngle)
        {
            result = this.IsPlayerInRayRange();
        }
        else if (this.IsOverPoint(this.player.transform.position, this.playerOffset))
        {
            result = true;
        }

        return result;
    }

    public bool IsPlayerInRayRange()
    {
        bool result = false;
        Vector3 direction = this.PlayerDistance.normalized;

        int layerMask = TagConstants.LAYER_PLAYER | TagConstants.LAYER_OBSTACLES;

        /* Check Player Hit */
        RaycastHit hit;
        if (Physics.Raycast(this.transform.position, direction, out hit, this.viewRange, layerMask) &&
            hit.collider.tag == TagConstants.TAG_PLAYER)
            result = true;

        return result;
    }

    public void SoundHeard(Vector3 location)
    {
        this.playerLastLocation = location;
        this.probSearch = this.probSearchFromNoise.NextValue();
    }

    public void NextWaypoint()
    {
        if (this.roundTripWaypoints)
            this.NextWaypointRoundTrip();
        else
            this.NextWaypointOneWay();
    }

    private void NextWaypointOneWay()
    {
        ++this.currentWaypoint;
        if (this.currentWaypoint >= this.waypoints.Length)
            this.currentWaypoint = 0;
    }

    private void NextWaypointRoundTrip()
    {
        this.currentWaypoint += this.waypointDirection;
        if (this.currentWaypoint == 0 || this.currentWaypoint == this.waypoints.Length-1)
            this.waypointDirection *= -1;
    }

    #endregion

    #region Unity Methods

    void Start () 
    {
        this.player = GameControl.FindPlayer();
        this.Init(EnemyPatrolState.Instance);
    }

    void OnTriggerEnter(Collider other) 
    {
        if (other.collider.tag == TagConstants.TAG_WAYPOINT)
            this.lastWaypointHit = other.collider.GetComponent<WaypointControl>();

        this.State.OnAction(ActionConstants.TRIGGER, this, other); 
    }

    #endregion

    #region StateBehaviour

    public override void OnUpdate()
    {
        
    }

    public override EnemyControl GetBehaviuor()
    {
        return this;
    }

    #endregion
}
